當頁面很多時,可進一步透過巢狀路由來管理頁面,讓頁面架構更清楚。以 Google Podcast 為例,下面有一個 Bottom Navigation 。其中媒體庫的頁面中有四個連結「訂閱」、「待播清單」、「下載內容」、「紀錄」,點擊訂閱後則會進到訂閱頁。

稍加拆解會發現下方 Bottom Navigation 算一個 Navigator ,包含三個 Screen 「首頁」、「探索」、「媒體庫」。而媒體庫本身也算一個 Navigator ,包含四個 Screen 「訂閱」、「待播清單」、「下載內容」、「紀錄」。這就是所謂的巢狀路由。
現在讓我們嘗試撰寫一個巢狀路由架構。為了簡化複雜度,讓我們直接利用前面已經做好的 SettingsScreen 改寫,使他底下多出帳號管理 AccountScreen 和語言設定 LanguageScreen 。
創建 AccountScreen 和 LanguageScreen 。
function AccountScreen() {
  return (
    <View>
      <Text>帳號管理</Text>
    </View>
  );
}
function LanguageScreen() {
  return (
    <View>
      <Text>語言設定</Text>
    </View>
  );
}
接著改寫 SettingsScreen ,基本架構就像前面講過的 Stack Navigation ,只是為了方便判別他是個 Stack ,將元件名稱更改成 SettingsStack。 BottomNavigation 引入的元件,也別忘了一併更改名稱:
import {createNativeStackNavigator} from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
function SettingsStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="AccountScreen" component={AccountScreen} />
      <Stack.Screen name="LanguageScreen" component={LanguageScreen} />
    </Stack.Navigator>
  );
}
完成後, AccountScreen 和 LanguageScreen 就會被掛在 SettingStack 的路由之下。
為了讓進入 SettingStack 時,可以有一個菜單頁能進 AccountScreen 和 LanguageScreen ,可以再製作一個 SettingsMenuScreen 元件:
function SettingsMenuScreen({navigation}) {
  return (
    <View>
      <TouchableOpacity onPress={() => navigation.navigate('AccountScreen')}>
        <Text>帳號管理</Text>
      </TouchableOpacity>
      <TouchableOpacity onPress={() => navigation.navigate('LanguageScreen')}>
        <Text>語言設定</Text>
      </TouchableOpacity>
    </View>
  );
}
再引入 SettingStack 中:
function SettingStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="SettingsMenuScreen" component={SettingsMenuScreen} />
      <Stack.Screen name="AccountScreen" component={AccountScreen} />
      <Stack.Screen name="LanguageScreen" component={LanguageScreen} />
    </Stack.Navigator>
  );
}

最後,運用前面提過的 options 屬性,我們能把 Settings 這個 Header 隱藏。
function BottomeNavigation() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen
        name="Settings"
        component={SettingsStack}
        options={{
          headerShown: false,
          headerTransparent: true,
          headerBackground: () => null,
        }}
      />
    </Tab.Navigator>
  );
}


運用上面所做的,來看一下巢狀路由有哪些特性:
最後補充一個特殊情況:要如何從一個 Stack ,進到另一個 Stack 中的巢狀路由下的子路由呢?
為了模擬出問題,我們建立一個 HomeStack ,並將他和 SettingsStack 一起掛在 BottomNavigation 底下:
function HomeStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="HomeScreen" component={HomeScreen} />
    </Stack.Navigator>
  );
}
function BottomeNavigation() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeStack} />
      <Tab.Screen
        name="Settings"
        component={SettingsStack}
        options={{
          headerShown: false,
          headerTransparent: true,
          headerBackground: () => null,
        }}
      />
    </Tab.Navigator>
  );
}
現在 HomeScreen 和 AccountScreen 分別被掛在 HomeStack 與 SettingsStack 之下。要從 HomeScreen 跳到 AccountScreen ,需要在第一個參數提供 Stack name ,在第二個參數附上有真正 Screen 名稱的物件。
function HomeScreen({navigation}) {
  return (
    <View>
      <Text>Home</Text>
      <TouchableOpacity
        onPress={() =>
          navigation.navigate('Settings', {screen: 'AccountScreen'})
        }>
        <Text>帳號管理</Text>
      </TouchableOpacity>
    </View>
  );
}